package com.foreveross.crawl.adapter.sub.impl20140402.v3;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.NavigableSet;
import java.util.Set;
import java.util.TreeSet;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.Source;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.select.Elements;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.foreveross.crawl.adapter.AbstractAdapter;
import com.foreveross.crawl.adapter.PlaneInfoEntityBuilder;
import com.foreveross.crawl.common.exception.self.PageErrorResultException;
import com.foreveross.crawl.common.util.DateUtil;
import com.foreveross.crawl.common.util.RegHtmlUtil;
import com.foreveross.crawl.domain.airfreight.AbstractPlaneInfoEntity;
import com.foreveross.crawl.domain.airfreight.CabinEntity;
import com.foreveross.crawl.domain.airfreight.TransitEntity;
import com.foreveross.crawl.domain.airfreight.doub.CabinRelationEntity;
import com.foreveross.crawl.domain.airfreight.doub.DoublePlaneInfoEntity;
import com.foreveross.crawl.domain.airfreight.doub.ReturnCabinEntity;
import com.foreveross.crawl.domain.airfreight.doub.ReturnDoublePlaneInfoEntity;
import com.foreveross.crawl.domain.airfreight.doub.ReturnTransitEntity;
import com.foreveross.crawl.domain.airfreight.single.SinglePlaneInfoEntity;
import com.foreveross.crawl.exception.FlightInfoNotFoundException;
import com.foreveross.taskservice.common.bean.TaskModel;
import com.google.common.collect.Lists;
/**
 * 南航适配器
 */

public class CSAirAdapter extends AbstractAdapter {
	static String s;

	public CSAirAdapter(TaskModel taskQueue) {
		super(taskQueue);
	}
	
	private boolean selectMethod=true;
	
	private  double CHINA_FIXED_TAXES=170;//国内默认总税收
	
	private static String CNT="";
	
	private static Integer backCount=1;
	
	private boolean IS_FLIGHTS=true;
	
	private static Integer sleepTime=1000;//从Amadues回滚之前休息一下	
	
	@Override
	public List<Object> paraseToVo(Object obj) throws Exception {
		switch (super.getRouteType()) {
		case INTERNATIONAL_ROUND:
			if(selectMethod) return paraseToVoDI(obj);//国际往返
			else return paraseToVoDIhtml(obj);
		case INTERNATIONAL_ONEWAY:
			return paraseToVoSI(obj);//国际单程
		case DOMESTIC_ONEWAYTRIP:
			return paraseToVoS(obj);//国内单程
		}
		return null;
	}
	
	//国内单程
	public List<Object> paraseToVoS(Object fetchObject) throws Exception {
		if(!IS_FLIGHTS)
			throw new FlightInfoNotFoundException("没有相此航线");
			List<Object> list = new ArrayList<Object>();
			Document d =(Document)fetchObject;
			XPathFactory xpf = XPathFactory.newInstance();
			XPath xpath = xpf.newXPath();
			String root = "/page/FLIGHTS/SEGMENT/DATEFLIGHT/DIRECTFLIGHT/FLIGHT";
			String root2="/page/FLIGHTS/PLANES";
			String root3="/page/FLIGHTS/AIRPORTS";
			String root4="/page/FLIGHTS/SEGMENT";
			NodeList nodesFLIGHT = (NodeList) xpath.evaluate(root, d,XPathConstants.NODESET);
			NodeList planINFOs =  (NodeList) xpath.evaluate(root2, d,XPathConstants.NODESET);//解释飞机类型
			NodeList airportINFOs =  (NodeList) xpath.evaluate(root3, d,XPathConstants.NODESET);//停留机场名字
			NodeList tax = (NodeList) xpath.evaluate(root4, d,XPathConstants.NODESET);//税价
			//最高，低价（含税收）
			double hightPriceTax=0.0;
			double lowestPriceTax=0.0;
			//最高，低税收价
			double hightTax=0.0;
			double lowestTax=0.0;
			
			if(tax.getLength()>0){
				Node taxNode=tax.item(0);
				String ADULTFUELTAX=xpath.evaluate("ADULTFUELTAX", taxNode);//成年人税价
				String VCHILDFUELTAX=xpath.evaluate("CHILDFUELTAX", taxNode);//小孩税价
				hightTax+=Double.parseDouble(ADULTFUELTAX !=null ? ADULTFUELTAX:"0"); 
				lowestTax+=Double.parseDouble(ADULTFUELTAX !=null ? ADULTFUELTAX:"0"); 
				//lowestTax+=Double.parseDouble(ADULTFUELTAX !=null ? ADULTFUELTAX:"0");
			}
			
			String planStyle="PLANE";
			String ariports="AIRPORT";
			Map<String ,String> planStyleMap=new HashMap<String ,String>();//存储机型
			Map<String ,String> airportNameMap=new HashMap<String ,String>();//存储机场名
			Map<String,String> taxT=new HashMap<String,String>();//存储税价
			try {
				NodeList planStyleLists = (NodeList) xpath.evaluate(planStyle,planINFOs.item(0), XPathConstants.NODESET);// 机型信息
				if (planStyleLists.getLength() > 0) {
					for (int p = 0; p < planStyleLists.getLength(); p++) {
						Node planStyles = planStyleLists.item(p);
						String planyStyle = xpath.evaluate("CODE", planStyles);// 787
						String ZHplanyStyleName = xpath.evaluate("ZHNAME",planStyles);// 波音787
						String planyStyleName = xpath.evaluate("ENNAME",planStyles);// B787
						String airportTax=xpath.evaluate("AIRPORTTAX", planStyles);//机场税
						if(airportTax !=null ){	taxT.put(airportTax, airportTax);}
						planStyleMap.put(planyStyle, ZHplanyStyleName);
					}
				}
			} catch (Exception e) {
				logger.error("没有机型信息!");
			}
			if(taxT.size()>0){
				hightTax+=Double.parseDouble(priceS(taxT)[0]);
				lowestTax+=Double.parseDouble(priceS(taxT)[1]);
			}
			try{
				NodeList airportLists= (NodeList) xpath.evaluate(ariports,airportINFOs.item(0),XPathConstants.NODESET);//机场名
				if(airportLists.getLength()>0){
					for (int ap = 0; ap < airportLists.getLength(); ap++) {
						Node airportNames = airportLists.item(ap);
						String airportCode = xpath.evaluate("CODE", airportNames);//机场三字码
						String airportName = xpath.evaluate("ENNAME",airportNames);//机场名
						airportNameMap.put(airportCode, airportName);
					}
				}
			}catch(Exception e){
				logger.error("没有机场名相关信息!");
			}
			for (int i = 0; i < nodesFLIGHT.getLength(); i++) {
				Node n = nodesFLIGHT.item(i);
				String FLIGHTNO = xpath.evaluate("FLIGHTNO", n);
				String FLIGHTTYLE=xpath.evaluate("PLANE", n);//飞机类型代码
				String DEPTIME = xpath.evaluate("DEPTIME", n);
				String ARRTIME = xpath.evaluate("ARRTIME", n);
				String TIMEDURINGFLIGHT= xpath.evaluate("TIMEDURINGFLIGHT", n);//飞行总时间
				NodeList nodes = (NodeList) xpath.evaluate("CABINS/CABIN/ADULTPRICE", n, XPathConstants.NODESET);
				NavigableSet<Integer> ns = new TreeSet<Integer>();
				for (int b = 0; b < nodes.getLength(); b++) {
					Node dd = nodes.item(b);
					ns.add(Integer.parseInt(dd.getTextContent().trim()));
				}
				if(ns.size()==0) continue;
				//舱位信息
				NodeList cabins = (NodeList) xpath.evaluate("CABINS/CABIN", n, XPathConstants.NODESET);
				int length = cabins.getLength();
//				Set<CabinEntity> s = new HashSet<CabinEntity>();//老模版
				Set<com.foreveross.crawl.domain.airfreight.CabinEntity> s = new HashSet<com.foreveross.crawl.domain.airfreight.CabinEntity>();
				Map<String ,String> cabinTypePrice=new HashMap<String ,String>();
				List<Node> nodeList = new ArrayList<Node>();
				//过滤掉没有价钱的舱位
				for (int j = 0; j < length; j++) {
					Node cabin = cabins.item(j); 
//					DOMImplementationLS domImplLS = (DOMImplementationLS) cabin.getOwnerDocument().getImplementation();
//					LSSerializer serializer = domImplLS.createLSSerializer(); System.out.println( serializer.writeToString(cabin));
					String adultPrice = xpath.evaluate("ADULTPRICE", cabin);
					if("".equals(adultPrice))continue;
					nodeList.add(cabin);
				}
				length = nodeList.size();
				if(length==0) continue;
				List<String> priceLists=Lists.newArrayList();//存储所有的价格
				for (int j = 0; j < length; j++) {
					Node node = nodeList.get(j);
					String name = xpath.evaluate("NAME", node);//小舱位名称
					String adultPrice = xpath.evaluate("ADULTPRICE", node);
					String BRANDTYPE = xpath.evaluate("BRAND;TYPE", node);//大舱位名称
					priceLists.add(adultPrice);
					//生舱位取数据已经变成了，全部取出的是子舱
					com.foreveross.crawl.domain.airfreight.CabinEntity c = new com.foreveross.crawl.domain.airfreight.CabinEntity();
					c.setSubCabinName(name);
					c.setPrice(Double.parseDouble(adultPrice));
					c.setCabinType(getCabinType(BRANDTYPE));
					//c.setCabinType(this.getCabinType(name));
//					c.setLevel(2);
					if(cabinTypePrice.get(name)!=null){
						String minPirce=this.compareString(cabinTypePrice.get(name), adultPrice);
						cabinTypePrice.put(name, minPirce);
					}else{
						cabinTypePrice.put(name, adultPrice);
					}
					s.add(c);
				}
				
				if(cabinTypePrice.size()>0){
					for(Map.Entry<String, String> cabMap:cabinTypePrice.entrySet()){
						String bigCabType=cabMap.getKey();
						String theCanPriceStr=cabMap.getValue();
						for(com.foreveross.crawl.domain.airfreight.CabinEntity c:s){
							if((c.getPrice()==Double.parseDouble(theCanPriceStr))&& c.getSubCabinName().equals(bigCabType)){
								if(this.getCabinType(bigCabType) !=null){
									c.setCabinType(this.getCabinType(bigCabType));
								}
							}
						}
					}
					
				}
				
				//新模版模型
				SinglePlaneInfoEntity singleEntity;
				singleEntity=(SinglePlaneInfoEntity)PlaneInfoEntityBuilder.buildPlaneInfo(taskQueue, 
						"CZ", "南航", "中国南方航空公司",  DEPTIME.trim(), ARRTIME.trim(), FLIGHTNO, (ns.size() == 0 ? "" : String.valueOf(ns.first())), 
						null, (ns.size() == 0 ? "" : String.valueOf(ns.last())), planStyleMap.size()>0?planStyleMap.get(FLIGHTTYLE):null);
				singleEntity.setCabins(s);
				singleEntity.setFlightDuration(flightTime(TIMEDURINGFLIGHT));
//				singleEntity.setFlightType(planStyleMap.size()>0?planStyleMap.get(FLIGHTTYLE):null);
				singleEntity.setSumHighestPrice(singleEntity.getTotalHighestPrice()+hightTax);
				singleEntity.setSumLowestPrice(singleEntity.getTotalLowestPrice()+lowestTax);
				singleEntity.setTotalLowestTaxesPrice(lowestTax);
				singleEntity.setTotalHighestTaxesPrice(hightTax);
				list.add(singleEntity);
			}
		
		return list;
	}
	
	
	
	public String getFlightDate(String time,String flightDateStr){
		String flgihtDate="";
		if(time !=null && !"".equals(time) && flightDateStr !=null && !"".equals(flightDateStr)){
			flgihtDate=flightDateStr+" "+time.substring(0,2)+":"+time.substring(2,4)+":00";
			return flgihtDate;
		}
		
		return null;
	}
	/**BRANDTYPE：F 头等  C公务舱  W高端经济舱  SW商务行  LX旅行家*/
	private String getCabinType(String BRANDTYPE){
		String data = null;
		if("F".equals(BRANDTYPE) || "A".equals(BRANDTYPE) || "P".equals(BRANDTYPE)){
			data = "头等舱";
		}else if("C".equals(BRANDTYPE) || "J".equals(BRANDTYPE)){
			data = "公务舱";
		}else if("W".equals(BRANDTYPE)){
			data = "高端经济舱";
		}else if("SW".equals(BRANDTYPE) || "Y".equals(BRANDTYPE) || "B".equals(BRANDTYPE) || "M".equals(BRANDTYPE) || "H".equals(BRANDTYPE)){
			data = "商务行";
		}else if("LX".equals(BRANDTYPE) || "K".equals(BRANDTYPE) || "L".equals(BRANDTYPE) || "E".equals(BRANDTYPE)|| "V".equals(BRANDTYPE)){
			data = "旅行家";
		}else if("Z".equals(BRANDTYPE)){
			data = "快乐飞";
		}
		return data;
	}
	
	//价格排序
	public List<Double> getPrice(List<String> priceLists){
		if(priceLists.size()>0){
			List<Double> prices=Lists.newArrayList();
			Double l=99999999.0,h=0.0;
			for(String price:priceLists){
				Double priceD=Double.parseDouble(price);
				if(priceD >h){
					h=priceD;
				}
				if(priceD <l){
					l=priceD;
				}
				
			}
			prices.add(h);
			prices.add(l);
			return prices;
		}
		return null;
	}
	
	//比较两个价格的大小
	public String compareString(String p1,String p2){
		
		if(p1 ==null || p1.equals("")){
			return p2;
		}
		if(p2 ==null || p2.equals("")){
			return p1;
		}
		
		if((p1 !=null || !p1.equals(""))&&(p2 !=null || !p2.equals(""))){
			if(Double.parseDouble(p1)>Double.parseDouble(p2)){
				return p2;
			}else{
				return p1;
			}
		}


		return null;
	}
	
	@Override
	public String getUrl() throws Exception {
		String url = null;
			url  = "http://b2c.csair.com/B2C40/detail-"
		+ taskQueue.getFromCity() + taskQueue.getToCity() + "-" + taskQueue.getFlightDate().replace("-", "") + "-1-0-0-0-1-0-0-0-1-0.g2c";
			return url;
	}
	/**
	 * 国际单程_适配器
	*/
	public List<Object> paraseToVoSI(Object fetchObject) throws Exception {
		logger.info("解析南航官网网站数据...");
		List<Object> list = new ArrayList<Object>();
		Document d = (Document) fetchObject;
		XPathFactory xpf = XPathFactory.newInstance();
		XPath xpath = xpf.newXPath();
		String root="/page/FLIGHTS/SEGMENT/DATEFLIGHT";
		String lowerPrices="page/FLIGHTS/SEGMENT";
		String root2="/page/FLIGHTS/PLANES";
		NodeList nodesFLIGHT = (NodeList) xpath.evaluate(root, d,XPathConstants.NODESET);		
		NodeList lowerPriceLists= (NodeList) xpath.evaluate(lowerPrices,d,XPathConstants.NODESET);//最低价信息
		
		NodeList planINFOs =  (NodeList) xpath.evaluate(root2, d,XPathConstants.NODESET);//解释飞机类型
		
		if(nodesFLIGHT.getLength()>0){//表示有航线存在
			//System.out.println("共有航线数："+nodesFLIGHT.getLength());
		for (int i = 0; i < nodesFLIGHT.getLength(); i++) {
			
			SinglePlaneInfoEntity sigPI =new SinglePlaneInfoEntity();
			ArrayList<TransitEntity> transitEntitys=new ArrayList<TransitEntity>();//存储中转
			Set<CabinEntity> cabinEntitys=new HashSet<CabinEntity>();
			

			//去程信息
			String flightNo=null;
			String deptime=null;
			String arrtime=null;
			String flightDate=null;
			String flightType=null;
			String fromCityCode=null;
			String toCityCode=null;
			
			//城市信息
			String fromCityNam=null;
			String toCityName=null;
			
			//最低价
			Double totalLowestPrice=9999.0;
			//最高价
			Double totalhigPrice=0.0;
			
			//最高，低价（含税收）
			double hightPriceTax=0.0;
			double lowestPriceTax=0.0;
			//最高，低税收价
			double hightTax=0.0;
			double lowestTax=0.0;
			
			Node n = nodesFLIGHT.item(i);
			String flighInfo="FLIGHT";
			String flightPrices="PRICES/PRICE";
			String CityLists="/page/FLIGHTS/AIRPORTS/AIRPORT";
			NodeList flighInfoLists= (NodeList) xpath.evaluate(flighInfo,n,XPathConstants.NODESET);//航班信息
			NodeList flightPriceLists= (NodeList) xpath.evaluate(flightPrices,n,XPathConstants.NODESET);//价格舱位信息
			NodeList flightCityLists= (NodeList) xpath.evaluate(CityLists,n,XPathConstants.NODESET);//城市信息
		//	System.out.println("+++"+flighInfoLists.getLength()+"+++"+flightPriceLists.getLength()+"+++"+flightCityLists.getLength()+"+++"+lowerPriceLists.getLength());
			
			if(flighInfoLists.getLength()>0){//长度为1 时候表示没有中转
				List<Map<String,String> > cityStrList=new ArrayList<Map<String,String>>();
				//城市信息
				if(flightCityLists.getLength()>2){//表示有中转信息 
					
					for(int c=0;c<flightCityLists.getLength();c++){
						Node cityInfo=flightCityLists.item(c);
						String fromCityCodes=xpath.evaluate("CODE",cityInfo);
						String fromCityCodesName=xpath.evaluate("ZHNAME",cityInfo);
						Map<String,String> cityMap=new HashMap<String ,String>();
						cityMap.put(fromCityCodes,fromCityCodesName );
						cityStrList.add(cityMap);
					}
				}
				
				Map<String ,String> planStyleMap=new HashMap<String ,String>();//存储机型
				try {
					String planStyle="PLANE";
					NodeList planStyleLists = (NodeList) xpath.evaluate(planStyle,planINFOs.item(0), XPathConstants.NODESET);// 机型信息
					if (planStyleLists.getLength() > 0) {
						for (int p = 0; p < planStyleLists.getLength(); p++) {
							Node planStyles = planStyleLists.item(p);
							String planyStyle = xpath.evaluate("PLANETYPE", planStyles);// 787
							String ZHplanyStyleName = xpath.evaluate("ZHPLANENAME",planStyles);// 波音787
							String planyStyleName = xpath.evaluate("ENPLANENAME",planStyles);// B787
							planStyleMap.put(planyStyle, ZHplanyStyleName);
						}
					}
				} catch (Exception e) {
					logger.error("没有机型信息!");
				}
				
				
				//舱位，价格信息
				double totalTax=0.0;
				for(int p=0;p<flightPriceLists.getLength();p++){
					CabinEntity cabinEntity=new CabinEntity();//舱位信息
					Node cabNum=flightPriceLists.item(p);
					Double adultPrice=Double.parseDouble(xpath.evaluate("ADULTPRICE", cabNum)+".0");//裸价
					Double adultcn=Double.parseDouble(xpath.evaluate("ADULTCN", cabNum)+".0");//机场税
					Double adultyq=Double.parseDouble(xpath.evaluate("ADULTYQ", cabNum)+".0");//燃油税
					Double adultxt=Double.parseDouble(xpath.evaluate("ADULTXT", cabNum)+".0");//其它税收
					String cabinType=getCabinTypeD(xpath.evaluate("CABINTYPE", cabNum));
					Double taxesPrice=adultxt+adultyq+adultcn;//总税收
					cabinEntity.setCabinType(cabinType);
					cabinEntity.setPrice(adultPrice);
					cabinEntity.setTaxesPrice(taxesPrice);//税收
					cabinEntity.setOriginalPrice(adultPrice+taxesPrice);//总计=祼价+税收
					if(totalhigPrice<adultPrice){
						totalhigPrice=adultPrice;
					}
					
					cabinEntitys.add(cabinEntity);
					totalTax=taxesPrice;
				}
				
				//最低价
				if(lowerPriceLists.getLength()==1){
					for(int l=0;l<lowerPriceLists.getLength();l++){
						Node loerPrices=lowerPriceLists.item(l);
						totalLowestPrice=Double.parseDouble(xpath.evaluate("MINPRICE",loerPrices)+".0");
					}
				}else{
					logger.error("出错：最低格超出两个。");
				}
				lowestPriceTax=totalLowestPrice+totalTax;
				hightPriceTax=totalhigPrice+totalTax;
				hightTax=totalTax;
				lowestTax=totalTax;
				
				
				//航班信息(包括中转)
				int flag=0;
				for(int m=0;m<flighInfoLists.getLength();m++){
					flag++;
					TransitEntity transitEntity=new TransitEntity();//中转
					
					Node flightInfo=flighInfoLists.item(m);
					String flightNos= xpath.evaluate("FLIGHTNO",flightInfo);
					String deptimes= xpath.evaluate("DEPTIME",flightInfo);
					String arrtimes= xpath.evaluate("ARRTIME",flightInfo);
					String flightDates=deptimes.split("T")[0];
					String flightTypes=xpath.evaluate("PLANE",flightInfo);
					flightTypes=planStyleMap.get(flightTypes) !=null ?planStyleMap.get(flightTypes) :null;
					String fromCityCodes=xpath.evaluate("DEPPORT",flightInfo);
					String toCityCodes=xpath.evaluate("ARRPORT",flightInfo);
					
					if(flag==1){//表示去程非中转信息
						flightNo=flightNos;
						deptime=deptimes;
						flightDate=flightDates;
						flightType=flightTypes;
						fromCityCode=fromCityCodes;
						toCityCode=toCityCodes;
						
						sigPI.setFlightDate(taskQueue.getFlightDate());
						sigPI.setFlightNo(flightNo);
						sigPI.setStartTime(getDates(deptime));
						sigPI.setFlightType(flightType);
						sigPI.setFromCity(taskQueue.getFromCity());
				//		sigPI.setToCity(toCityCode);
						
					}
					if(flighInfoLists.getLength()>1){//表示有中转信息，保存中转信息
						transitEntity.setFlightNo(flightNos);
						transitEntity.setStartTime(getDates(deptimes));
						transitEntity.setEndTime(getDates(arrtimes));
						transitEntity.setFlightType(flightTypes);
						transitEntity.setFromAirPort(fromCityCodes);
						transitEntity.setToAirPort(toCityCodes);
						
						transitEntity.setCarrierFullName("中国南方航空公司");
						transitEntity.setCarrierKey("CZ");
						transitEntity.setCarrierName("南航");
						
						transitEntitys.add(transitEntity); 
					}
					
					if(flag==flighInfoLists.getLength()){//表示最后一次执行for循环
						arrtime=arrtimes;
						sigPI.setToCity(toCityCodes);
						sigPI.setEndTime(getDates(arrtime));
					}
				}
				
				
			}
			//组装航线
			
			//总价（不含税收）
			sigPI.setTotalHighestPrice(totalhigPrice);
			sigPI.setTotalLowestPrice(totalLowestPrice);
			//总价（含税收）
			sigPI.setSumHighestPrice(hightPriceTax);
			sigPI.setSumLowestPrice(lowestPriceTax);
			//税收
			sigPI.setTotalHighestTaxesPrice(hightTax);
			sigPI.setTotalLowestTaxesPrice(lowestTax);
			
			sigPI.setFromCityName(taskQueue.getFromCityName());
			sigPI.setToCityName(taskQueue.getToCityName());
			sigPI.setCreateTime(new Date());
			sigPI.setAreaName(taskQueue.getAreaName());					
			sigPI.setAreaCode(taskQueue.getAreaCode());
			sigPI.setGrabChannelId(taskQueue.getGrabChannelId());
			sigPI.setGrabChannelName(taskQueue.getGrabChannel());
			sigPI.setAttachHbaseKey(taskQueue.getAttachHbaseKey());
			sigPI.setCarrierFullName("中国南方航空公司");
			sigPI.setCarrierKey("CZ");
			sigPI.setCarrierName("南航");
			
			
			if(transitEntitys.size()>0){
				sigPI.setTransits(transitEntitys);
			}
			if(cabinEntitys.size()>0){
				sigPI.setCabins(cabinEntitys);
			}
			list.add(sigPI);
			
		}
		}
		rollbackProxyIp(true);
		return list;
	}
	
	/**
	 * 解析从南航进入Amadues对应session信息
	 * @reurn string
	*/
	public String getSessionInfo(Source sources){
		logger.info("开始解析session信息....");
		String sessionInfo="";
		try{
			List<Element> bodyList= sources.getAllElements("form");
			if(bodyList.size()>0){//正确的情况下只有一个body
				for(int i=0;i<bodyList.size();i++){
					String source=bodyList.get(i).toString();
					if(source.contains("jsessionid=")){
						sessionInfo=RegHtmlUtil.regStr(bodyList.get(i).toString(),"(jsessionid=[^\"|^\\?]*)");
						break;
					}
				}
			}
		}catch (Exception e) {
			logger.error("解析失败！");
			e.printStackTrace();
		}
		return sessionInfo;
	}
	
	
	/**
	 * 国际往返——适配器
	 */	
	//html(解释amadues网站)
	private List<Object> paraseToVoDIhtml(Object fetchObject)throws Exception{
		logger.info("解析amadues网站数据...");
		if(fetchObject !=null){
			List<Object> list = new ArrayList<Object>();
			DoublePlaneInfoEntity entity=null;
			ReturnDoublePlaneInfoEntity rEntity=null;
			String totalTax="0",total="0",sumTotal="0";
			try{
				org.jsoup.nodes.Document doc = Jsoup.parse(fetchObject.toString());
				List<org.jsoup.nodes.Element> tabLists=doc.select("table.tableFlightConf");
				if(tabLists.size()>0){
					Elements  priceStr=doc.select("tr.fared2");//价格信息
					total=priceStr.select("td:eq(2)").text().replaceAll(",", "").replaceAll("\\(", "");//裸价
					totalTax=priceStr.select("span#taxes_ADT").text().replaceAll(",", "").replaceAll("\\)", "");//税价总合
					sumTotal=priceStr.select("span#totalForATravellerType_ADT").text() !=null?priceStr.select("span#totalForATravellerType_ADT").text().split(" ")[0].replaceAll(",", ""):"0";//总价
					for(int tab=0;tab<tabLists.size();tab++){
						String statrtTimeStr=null;//去程出发时间
						String endTimeStr=null;//运程到达时间
						String RstatrtTimeStr=null;//返程出发时间
						String RendTimeStr=null;//返程到达时间
						String arrCodeName=null;//出发机场名
						String endCodeName=null;//到达机场名
						String flightTyle=null;//机型
						String flightNo=null;//航班号
						Long TstopTime=0l;//中转停留时间
						String cabinName=null;//舱位名称
						
						org.jsoup.nodes.Element table=tabLists.get(tab);
						List<org.jsoup.nodes.Element> tabs=table.select("tr td table tr td  table ");///航班信息
						TstopTime=Ttime(table.select("div.textChangeAirport").text());//中转时间
						if(tabs.size()>0){
							int gF=0,rF=0,gflightId=0,rflightId=0;
							for(int t=0;t<tabs.size();t++){
								org.jsoup.nodes.Element trT=tabs.get(t);
								if(t%2==0){
									if(tab==0){//去程 
										statrtTimeStr=TflightTime(trT.select("tr:eq(0) td.nowrap").text(),taskQueue.getFlightDate());//出发日期
										endTimeStr=TflightTime(trT.select("tr:eq(1) td.nowrap").text(),taskQueue.getFlightDate());//航班日期
									}else{//返程
										RstatrtTimeStr=TflightTime(trT.select("tr:eq(0) td.nowrap").text(),taskQueue.getReturnGrabDate());//出发日期
										RendTimeStr=TflightTime(trT.select("tr:eq(1) td.nowrap").text(),taskQueue.getReturnGrabDate());//航班日期
									}
									arrCodeName=TairportName(trT.select("tr:eq(0) td:eq(2)").text());//出发机场名
									endCodeName=TairportName(trT.select("tr:eq(1) td:eq(2)").text());//机场名
									if(tab==0 && gF==0){
										gF++;
										entity=PlaneInfoEntityBuilder.buildPlaneInfo(taskQueue, "CZ", null, null, statrtTimeStr, endTimeStr, flightNo, total, null, total, flightTyle,DoublePlaneInfoEntity.class);
									}else if(tab==1&&rF==0){
										rF++;
										rEntity=PlaneInfoEntityBuilder.buildPlaneInfo(taskQueue, "CZ", null,null, RstatrtTimeStr, RendTimeStr, flightNo, total, null, total, flightTyle,ReturnDoublePlaneInfoEntity.class);
									}
									
								}else{
									flightTyle=trT.select("tr td:eq(1)").text();//机型
								}
								if(t%2!=0){
									//组装信息（包括中转）
									flightNo=RegHtmlUtil.regStr(table.select("td#segAirline_"+tab+"_"+t%2) !=null?table.select("td#segAirline_"+tab+"_"+t%2).text():null,"([a-zA-Z]{2,5}\\d{1,2})");//航班号
									cabinName=table.select("td#segFareType_"+tab+"_"+t%2).text();//舱位信息
									if(tab==0){//去程中转
										if(gflightId==0){
											gflightId++;
											entity.setFlightNo(flightNo);
											entity.setFlightType(flightTyle);
//											entity.getCabins().add(e)
										}
										TransitEntity trEntity=PlaneInfoEntityBuilder.buildTransitEntity(
											flightNo, flightNo, "CZ", null, null, null, arrCodeName,null, endCodeName,flightTyle,TransitEntity.class);
									trEntity.setStayTime(TstopTime);
									trEntity.setCabinName(cabinName);
									entity.getTransits().add(trEntity);
									}
									if(tab==1){//返程中转
										if(rflightId==0){
											rflightId++;
											rEntity.setFlightNo(flightNo);
											rEntity.setFlightType(flightTyle);
										}
										ReturnCabinEntity rCabinE=PlaneInfoEntityBuilder.buildCabinInfo(
												cabinName, null, null, null, null, null, null, ReturnCabinEntity.class);
										ReturnTransitEntity rTr=PlaneInfoEntityBuilder.buildTransitEntity(
												flightNo, flightNo,"CZ", null,null,arrCodeName, null, endCodeName, null, null,ReturnTransitEntity.class);
										rTr.setStayTime(TstopTime);
										rTr.setCabinName(cabinName);
										rEntity.getReturnTransits().add(rTr);
										rEntity.getReturnCabins().add(rCabinE);
									}
								}
							}
						}
							//去程信息组装
							if(tab==0){
								entity.setSumLowestPrice(Double.parseDouble(sumTotal));
								entity.setSumHighestPrice(Double.parseDouble(sumTotal));
								entity.setTotalLowestTaxesPrice(Double.parseDouble(totalTax));
								entity.setTotalHighestTaxesPrice(Double.parseDouble(totalTax));
							}else{//返程信息组装
								rEntity.setSumLowestPrice(Double.parseDouble(sumTotal));
								rEntity.setSumHighestPrice(Double.parseDouble(sumTotal));
								rEntity.setTotalLowestTaxesPrice(Double.parseDouble(totalTax));
								rEntity.setTotalHighestTaxesPrice(Double.parseDouble(totalTax));
							}
					}
					
				}
				
			}catch (Exception e) {
				logger.error("解析错误");
				e.printStackTrace();
			}
			if(entity !=null){
				list.add(entity);
			}
			logger.info("Amadues success return size= "+list.size());
			rollbackProxyIp(true);
			return list;
		}
		logger.info("Amadues success return null");
		return null;
	}
	
	
	//JSON
	private List<Object> paraseToVoDI(Object fetchObject) throws Exception {
		logger.info("解析南航官网网站数据...");
		List<Object> list = new ArrayList<Object>();
		DoublePlaneInfoEntity doublePI = null;
		Document d =(Document)fetchObject;
		XPathFactory xpf = XPathFactory.newInstance();
		XPath xpath = xpf.newXPath();
		String root="/page/FLIGHTS/DATEFLIGHT";
		String root2="/page/FLIGHTS/PLANES";
		String root3="/page/FLIGHTS/AIRPORTS";
		NodeList nodesFLIGHT = (NodeList) xpath.evaluate(root, d,XPathConstants.NODESET);
		NodeList planINFOs =  (NodeList) xpath.evaluate(root2, d,XPathConstants.NODESET);//解释飞机类型
		NodeList airportINFOs =  (NodeList) xpath.evaluate(root3, d,XPathConstants.NODESET);//停留机场名字
		String planBeginDate="";
		String planReturnBeginDate="";
		String planReturnArraDate="";
		String planArraDate="";
		String flightType="";
		String flightReType="";
		String flightId="";
		String flightReId="";
		String depPort="";
		String arrPort="";
		String depRePort="";
		String arrRePort="";
		String planActurllyFlightNo="";
		String planActurllyReFlightNo="";
		//最高，低价（不含税收）
		double hightPrice=0.0;
		double lowestPrice=9999999999.0;
		//最高，低价（含税收）
		double hightPriceTax=0.0;
		double lowestPriceTax=0.0;
		//最高，低税收价
		double hightTax=0.0;
		double lowestTax=0.0;
		
		
		String planStyle="PLANE";
		String ariports="AIRPORT";
		Map<String ,String> planStyleMap=new HashMap<String ,String>();//存储机型
		Map<String ,String> airportNameMap=new HashMap<String ,String>();//存储机场名
		try {
			NodeList planStyleLists = (NodeList) xpath.evaluate(planStyle,planINFOs.item(0), XPathConstants.NODESET);// 机型信息
			if (planStyleLists.getLength() > 0) {
				for (int p = 0; p < planStyleLists.getLength(); p++) {
					Node planStyles = planStyleLists.item(p);
					String planyStyle = xpath.evaluate("PLANETYPE", planStyles);// 787
					String ZHplanyStyleName = xpath.evaluate("ZHPLANENAME",planStyles);// 波音787
					String planyStyleName = xpath.evaluate("ENPLANENAME",planStyles);// B787
					planStyleMap.put(planyStyle, ZHplanyStyleName);
				}
			}
		} catch (Exception e) {
			logger.error("没有机型信息!");
		}
		try{
			NodeList airportLists= (NodeList) xpath.evaluate(ariports,airportINFOs.item(0),XPathConstants.NODESET);//机场名
			if(airportLists.getLength()>0){
				for (int ap = 0; ap < airportLists.getLength(); ap++) {
					Node airportNames = airportLists.item(ap);
					String airportCode = xpath.evaluate("CODE", airportNames);//机场三字码
					String airportName = xpath.evaluate("ENNAME",airportNames);//机场名
					airportNameMap.put(airportCode, airportName);
				}
			}
		}catch(Exception e){
			logger.error("没有机场名相关信息!");
		}
		
		for (int i = 0; i < nodesFLIGHT.getLength(); i++) {
			Set<CabinRelationEntity>cabinRelationEntitys=new HashSet<CabinRelationEntity>();
			Node n = nodesFLIGHT.item(i);
			String segments="SEGMENT";
			NodeList segmentsLists= (NodeList) xpath.evaluate(segments,n,XPathConstants.NODESET);//航班信息
			String priceStyle="PRICES/PRICE";
			NodeList priceStyleLists= (NodeList) xpath.evaluate(priceStyle,n,XPathConstants.NODESET);//价格信息
			
			if(priceStyleLists.getLength()>0){//表示有舱位
			/*
			 * segmentsLists.getLength()的值一般为2，因为是往返程;
			 * 第1次是去程，第2次是返程
            */			
			int flag=0;
			
			if(segmentsLists.getLength()>2){
				logger.error("航线出错了!。");
				return null;
			}
			Set<DoublePlaneInfoEntity> goPlanInfos=new HashSet<DoublePlaneInfoEntity>();//去程信息总和
			doublePI=new DoublePlaneInfoEntity();
			
			Set<ReturnDoublePlaneInfoEntity> returnPlanInfos=new HashSet<ReturnDoublePlaneInfoEntity>(); //返程信息总和
			ReturnDoublePlaneInfoEntity returnPI=new ReturnDoublePlaneInfoEntity();
			AbstractPlaneInfoEntity planeReturnInfoEntity = new ReturnDoublePlaneInfoEntity() ;
			
			Set<com.foreveross.crawl.domain.airfreight.CabinEntity> cabinSet =new HashSet<com.foreveross.crawl.domain.airfreight.CabinEntity>();
			Set<ReturnCabinEntity> returnCabinSet=new HashSet<ReturnCabinEntity> ();

			//处理舱位信息(暂时只考虑直达的关系，不考虑中转的)
			for(int l=0;l<priceStyleLists.getLength();l++){//priceStyleLists.getLength()共有多少个舱位类型（头等舱，公务舱......）
				com.foreveross.crawl.domain.airfreight.CabinEntity cabinEn=new com.foreveross.crawl.domain.airfreight.CabinEntity();
				ReturnCabinEntity recabinEn=new ReturnCabinEntity();
				Node cabNum=priceStyleLists.item(l);
				Double adultPrice=Double.parseDouble(xpath.evaluate("ADULTPRICE", cabNum));//裸价
				String cabinType=getCabinTypeD(xpath.evaluate("CABINTYPE", cabNum));
				
				Double adultcn=Double.parseDouble(xpath.evaluate("ADULTCN", cabNum)+".0");//机场税
				Double adultyq=Double.parseDouble(xpath.evaluate("ADULTYQ", cabNum)+".0");//燃油税
				Double adultxt=Double.parseDouble(xpath.evaluate("ADULTXT", cabNum)+".0");//其它税收
				Double taxesPrice=adultxt+adultyq+adultcn;//总税收
				//子舱位
				String subCabins="ADULTCABINS/CABIN";
				NodeList subCabinLists =(NodeList)xpath.evaluate(subCabins,cabNum,XPathConstants.NODESET);
				if(subCabinLists.getLength()>0){
					for(int c=0;c<subCabinLists.getLength();c++){
						Node sbuCabins=subCabinLists.item(c);
						
					}
				}
				
				
				if(adultPrice>hightPrice){
					hightPrice=adultPrice;
					hightTax=taxesPrice;
					hightPriceTax=adultPrice+taxesPrice;
				}
				if(adultPrice<lowestPrice){
					lowestPrice=adultPrice;
					lowestTax=taxesPrice;
					lowestPriceTax=adultPrice+taxesPrice;
				}
				CabinRelationEntity cabinRelationEntity=new CabinRelationEntity();
//				cabinEn.setTaxesPrice(taxesPrice);//税收
//				cabinEn.setOriginalPrice(adultPrice+taxesPrice);//总计=祼价+税收
				cabinEn.setCabinType(cabinType);
				recabinEn.setCabinType(cabinType);
				recabinEn.setId(cabinEn.getId());
//				cabinEn.setPrice(adultPrice);
				cabinRelationEntity.setTaxesPrice(taxesPrice);
				cabinRelationEntity.setTotalFullPrice(adultPrice+taxesPrice);
				cabinRelationEntity.setFullPrice(adultPrice);
				cabinRelationEntity.setCabinId(cabinEn.getId());
				cabinRelationEntity.setReturnCabinId(recabinEn.getId());
				cabinRelationEntitys.add(cabinRelationEntity);
				cabinSet.add(cabinEn);
				returnCabinSet.add(recabinEn);
			}
			
			
			//处理航班信息
			for(int k=0;k<segmentsLists.getLength();k++){
				
				ArrayList<TransitEntity> transitSet=new ArrayList<TransitEntity>();
				ArrayList<ReturnTransitEntity> reTransitSet=new ArrayList<ReturnTransitEntity>();
				flag++;
				Node citysInfos = segmentsLists.item(k);
				String fromCityNameCode= xpath.evaluate("DEPCITY",citysInfos);//出发城市PORT
				String toCityNameCode= xpath.evaluate("ARRCITY",citysInfos);//到达城市PORT
				String showFlights="FLIGHT";
				NodeList flightInfos=(NodeList) xpath.evaluate(showFlights,citysInfos,XPathConstants.NODESET);
				int getBT=0;//用来判断获取航班起飞日期标记
				if(flightInfos.getLength()>1){//大于1表示有中转
					for(int m=0;m<flightInfos.getLength();m++){
						getBT++;
						Node flightInfoList=flightInfos.item(m);
						
						String depport=xpath.evaluate("DEPPORT",flightInfoList);
						String arrport=xpath.evaluate("ARRPORT",flightInfoList);
						
						String flightNo = xpath.evaluate("FLIGHTNO", flightInfoList);
						String deptime = xpath.evaluate("DEPTIME", flightInfoList).trim();
						String arrtime = xpath.evaluate("ARRTIME", flightInfoList).trim();
						String planeNs=xpath.evaluate("PLANE",flightInfoList);//飞机类型，例如空客333
						String planeN=planStyleMap.size()>0 ?planStyleMap.get(planeNs):null;
						if(flag==1&&flightInfos.getLength()>1 && getBT==1){//去程信息
							planBeginDate=deptime.replaceAll("T", " ");
							flightId=flightNo;
							flightType=planeN;
							depPort=depport;
						}if(getBT==flightInfos.getLength() && flag==1 && flightInfos.getLength()>1){
							planArraDate=arrtime.replaceAll("T", " ");//去程到达日期
							arrPort=arrport;
						}
						if(flag==2&&flightInfos.getLength()>1 && getBT==1){
							planReturnBeginDate=deptime.replaceAll("T", " ");//返程出发时间
							flightReId=flightNo;
							flightReType=planeN;
							depRePort=depport;
							
						}
						if(getBT==flightInfos.getLength() && flag==2 && flightInfos.getLength()>1){
							planReturnArraDate=arrtime.replaceAll("T", " ");//返程到达日期
							arrRePort=arrport;
						}
						
						String ocFlightNo ="";
						if(xpath.evaluate("CODESHARE",flightInfoList).equals("true")){//表示有承运信息（实际航班）
							ocFlightNo=xpath.evaluate("OCFLIGHTNO", flightInfoList);
						}
						
						//组装中转信息
						if(flag==1){//表示去程中转信息
							TransitEntity transitEntity = new TransitEntity();
							transitEntity.setFlightNo(flightNo);
							transitEntity.setFlightType(planeN);
							transitEntity.setStartTime(getDates(deptime));
							transitEntity.setEndTime(getDates(arrtime));
							transitEntity.setFromAirPort(depport);
							transitEntity.setFromAirPortName(airportNameMap.size()>0? airportNameMap.get(depport):null);
							transitEntity.setToAirPort(arrport);
							transitEntity.setToAirPortName(airportNameMap.size()>0?airportNameMap.get(arrport):null);
							transitEntity.setCarrierKey("CZ");
							transitEntity.setCarrierName("南航");
							transitEntity.setCarrierFullName("中国南方航空公司");
							transitEntity.setActuallyFlightNo(ocFlightNo);
							
							transitSet.add(transitEntity);//中转
							
						}if(flag==2){//表示返程中转信息
							ReturnTransitEntity reTransitE=new ReturnTransitEntity();
							reTransitE.setFlightNo(flightNo);
							reTransitE.setFlightType(planeN);
							reTransitE.setStartTime(getDates(deptime));
							reTransitE.setEndTime(getDates(arrtime));
							reTransitE.setFromAirPort(depport);
							reTransitE.setFromAirPortName(airportNameMap.size()>0?airportNameMap.get(depport):null);
							reTransitE.setToAirPort(arrport);
							reTransitE.setToAirPortName(airportNameMap.size()>0?airportNameMap.get(arrport):null);
							reTransitE.setCarrierKey("CZ");
							reTransitE.setCarrierName("南航");
							reTransitE.setCarrierFullName("中国南方航空公司");
							reTransitE.setActuallyFlightNo(ocFlightNo);
							
							reTransitSet.add(reTransitE);
							
						}
					}
				}if(flightInfos.getLength()==1){//没有中转信息
					getBT++;
					Node flightInfoList=flightInfos.item(0);
					String flightNo = xpath.evaluate("FLIGHTNO", flightInfoList);
					String deptime = xpath.evaluate("DEPTIME", flightInfoList).trim();
					String arrtime = xpath.evaluate("ARRTIME", flightInfoList).trim();
					String planeN=xpath.evaluate("PLANE",flightInfoList)  ;
					planeN=	planStyleMap.size()>0 ?planStyleMap.get(planeN):null;//飞机类型，例如空客333
					String depport=xpath.evaluate("DEPPORT",flightInfoList);
					String arrport=xpath.evaluate("ARRPORT",flightInfoList);
					String ocFlightNo ="";
					if(xpath.evaluate("CODESHARE",flightInfoList).equals("true")){//表示有承运信息（实际航班）
						ocFlightNo=xpath.evaluate("OCFLIGHTNO", flightInfoList);
					}
					if(flag==1 && getBT==1 && flightInfos.getLength()==1){
						planBeginDate=deptime;//去程起飞日期
						flightId=flightNo;
						flightType=planeN;
						planActurllyFlightNo=ocFlightNo;
						depPort=depport;
						arrPort=arrport;
					}if(flag==1 && getBT==1 && flightInfos.getLength()==1){
						planArraDate=arrtime;//去程到达日期
					}if(flag==2 && getBT==1 && flightInfos.getLength()==1){
						planReturnBeginDate=deptime;//返程起飞日期
						flightReId=flightNo;
						flightReType=planeN;
						planActurllyReFlightNo=ocFlightNo;
						depRePort=depport;
						arrRePort=arrport;
						
					}
					if(flag==2 && getBT==1 && flightInfos.getLength()==1){
						planReturnArraDate=arrtime;//返程到达日期
					}
					
				}
				
				//组装基本信息(去程，返程)
								
				//得到第一个航班号，航班起飞时间，飞机类型作为第一个信息展现
				
				if(flag==1){//组装去程信息
					
					if(transitSet.size()>0){//去程中转信息
						doublePI.setTransits(transitSet);
					}
					doublePI.setFromCity(fromCityNameCode);
					doublePI.setToCity(toCityNameCode);
					if(!planBeginDate.equals("")){
						doublePI.setStartTime(getDates(planBeginDate));
						doublePI.setFlightDate(taskQueue.getFlightDate());
					}
					
					if(!planArraDate.equals("")){
						doublePI.setEndTime(getDates(planArraDate));
					}
					doublePI.setCreateTime(new Date());
					doublePI.setFlightNo(flightId);
					doublePI.setFromCity(taskQueue.getFromCity());
					doublePI.setToCity(taskQueue.getToCity());
					doublePI.setFlightType(flightType);
					/*if(!planReturnBeginDate.equals("")){
						doublePI.setStartTime(getDates(planReturnBeginDate));
					}
					if(!planReturnArraDate.equals("")){
						doublePI.setEndTime(getDates(planReturnArraDate));
					}*/
				
					doublePI.setCarrierFullName("中国南方航空公司");
					doublePI.setCarrierKey("CZ");
					if(!planActurllyFlightNo.equals("")){
						doublePI.setActuallyFlightNo(planActurllyFlightNo);
					}
					
					doublePI.setCarrierName("南航");
					doublePI.setAreaCode(taskQueue.getAreaCode());
					doublePI.setAreaName(taskQueue.getAreaName());					
					doublePI.setGrabChannelId(taskQueue.getGrabChannelId());
					doublePI.setGrabChannelName(taskQueue.getGrabChannel());
					doublePI.setAttachHbaseKey(taskQueue.getAttachHbaseKey());
					doublePI.setFlightReturnDate(taskQueue.getReturnGrabDate());
				}
				
				if(flag==2){//组装返程信息
					
					if(reTransitSet.size()>0){//返程中转信息
						returnPI.setReturnTransits(reTransitSet);
					}
					
					if(returnCabinSet.size()>0){
						returnPI.setReturnCabins(returnCabinSet);
					}
					
					returnPI.setFromCity(depRePort);
					returnPI.setToCity(arrRePort);
					if(!planReturnBeginDate.equals("") ){
						returnPI.setStartTime(getDates(planReturnBeginDate));
						returnPI.setFlightDate(taskQueue.getReturnGrabDate());//planReturnBeginDate.split("T")[0]
					}
					if(!planReturnArraDate.equals("")){
						returnPI.setEndTime(getDates(planReturnArraDate));
					}
					returnPI.setTotalLowestPrice(lowestPrice);
					returnPI.setTotalHighestPrice(hightPrice);
					returnPI.setSumHighestPrice(hightPriceTax);
					returnPI.setSumLowestPrice(lowestPriceTax);
					returnPI.setTotalHighestTaxesPrice(hightTax);
					returnPI.setTotalLowestTaxesPrice(lowestTax);
					returnPI.setFlightType(flightReType);
					returnPI.setFlightNo(flightReId);
					returnPI.setAreaName(taskQueue.getAreaName());
					returnPI.setAreaCode(taskQueue.getAreaCode());
					returnPI.setFromCityName(taskQueue.getToCityName());//返程中回来城市
					returnPI.setToCityName(taskQueue.getFromCityName());//返程到达城市
					returnPI.setCarrierFullName("中国南方航空公司");
					returnPI.setCarrierKey("CZ");
					returnPI.setCarrierName("南航");
					returnPI.setGrabChannelId(taskQueue.getGrabChannelId());
					returnPI.setGrabChannelName(taskQueue.getGrabChannel());
					returnPI.setAttachHbaseKey(taskQueue.getAttachHbaseKey());
					returnPI.setStartTime(getDates(planReturnBeginDate));
					returnPI.setEndTime(getDates(planReturnArraDate));
					returnPI.setCreateTime(new Date());
					//总价（不含税收）
					planeReturnInfoEntity.setTotalHighestPrice(hightPrice);
					planeReturnInfoEntity.setTotalLowestPrice(lowestPrice);
					//总价（含税收）
					planeReturnInfoEntity.setSumHighestPrice(hightPriceTax);
					planeReturnInfoEntity.setSumLowestPrice(lowestPriceTax);
					//税收
					planeReturnInfoEntity.setTotalHighestTaxesPrice(hightTax);
					planeReturnInfoEntity.setTotalLowestTaxesPrice(lowestTax);
					planeReturnInfoEntity.setCreateTime(new Date());
					planeReturnInfoEntity.setFlightNo(flightReId);
					planeReturnInfoEntity.setFromCity(depRePort );
					planeReturnInfoEntity.setFromCityName(taskQueue.getToCityName());//返程中回来城市
					planeReturnInfoEntity.setToCity(arrRePort);
					planeReturnInfoEntity.setToCityName(taskQueue.getFromCityName());//返程到达城市
					planeReturnInfoEntity.setFlightType(flightReType);
					planeReturnInfoEntity.setAreaName(taskQueue.getAreaName());					
					planeReturnInfoEntity.setAreaCode(taskQueue.getAreaCode());
					planeReturnInfoEntity.setGrabChannelId(taskQueue.getGrabChannelId());
					planeReturnInfoEntity.setGrabChannelName(taskQueue.getGrabChannel());
					planeReturnInfoEntity.setAttachHbaseKey(taskQueue.getAttachHbaseKey());
					planeReturnInfoEntity.setStartTime(getDates(planReturnBeginDate));
					planeReturnInfoEntity.setEndTime(getDates(planReturnArraDate));
					planeReturnInfoEntity.setCarrierFullName("中国南方航空公司");
					planeReturnInfoEntity.setCarrierKey("CZ");
					planeReturnInfoEntity.setCarrierName("南航");
					if(!planActurllyReFlightNo.equals("")){
						planeReturnInfoEntity.setActuallyFlightNo(planActurllyReFlightNo);
						returnPI.setActuallyFlightNo(planActurllyReFlightNo);
					}
					returnPI.setPlaneInfoEntity(planeReturnInfoEntity);
					returnPlanInfos.add(returnPI);
				}
			}
			
			//组装此航线的信息
			
			//总价（含税收）
			doublePI.setSumHighestPrice(hightPriceTax);
			doublePI.setSumLowestPrice(lowestPriceTax);
			//税收
			doublePI.setTotalHighestTaxesPrice(hightTax);
			doublePI.setTotalLowestTaxesPrice(lowestTax);
			doublePI.setCabins(cabinSet);
			doublePI.setReturnPlaneInfos(returnPlanInfos);
			doublePI.setTotalLowestPrice(lowestPrice);
			doublePI.setTotalHighestPrice(hightPrice);
			doublePI.setFromCityName(taskQueue.getFromCityName());
			doublePI.setToCityName(taskQueue.getToCityName());
			if(cabinRelationEntitys.size()>0){
				doublePI.setCabinRelations(cabinRelationEntitys);
			}
			
			list.add(doublePI);
			// list.add(PlaneInfoEntityBuilder.creatDoublePlanInfoEs(hightPrice,
			// lowestPrice,cabinSet,returnPI,doublePI));
			}
		}
		
		logger.info("CSair success return size= "+list.size());
		rollbackProxyIp(true);
		return list;
	}

	/**
	 * 获得国际往返解析地址	
	 */	
	private String getUrlDouble() throws Exception {
		//组装适配器地址
		StringBuilder url = new StringBuilder("http://b2c.csair.com/B2C40/detail-");
		url.append(taskQueue.getFromCity());
		url.append(taskQueue.getToCity());
		url.append("-");
		url.append(taskQueue.getFlightDate().replace("-", ""));
		url.append(taskQueue.getReturnGrabDate().replace("-", ""));
		url.append("-1-0-0-0-1-0-1-0-0-0.g2c");
//		System.out.println(url.toString());
		return url.toString();
	}
	

	/**
	 * 获得国际单程解析地址	
	 */	
	private String getUrlInternationalSI() throws Exception{
		StringBuilder url = new StringBuilder("http://b2c.csair.com/B2C40/detail-");
		url.append(taskQueue.getFromCity());
		url.append(taskQueue.getToCity());
		url.append("-");
		url.append(taskQueue.getFlightDate().replace("-", ""));
		url.append("-1-0-0-0-1-0-1-0-1-0.g2c");
//		System.out.println(url.toString());
		return url.toString();
	}
	
	/**
	 * 国际往返舱位
	 */	
	private String getCabinTypeD(String BRANDTYPE){
		String data = null;
		if("FIRST".equals(BRANDTYPE)){
			data = "头等舱";
		}else if("BUSINESS".equals(BRANDTYPE)){
			data = "公务舱";
		}else if("PREMIUMECONOMY".equals(BRANDTYPE)){
			data = "高端经济舱";
		}else if("ECONOMY".equals(BRANDTYPE)){
			data = "经济舱";
		}
		return data;
	}
	
	/**
	 * 处理时间格式
	 * XX小时XX分钟
	*/
	public Long flightTime(String str){
		if(str!=null && !str.equals("")){
			Long h=Long.parseLong(str.split("小时")[0]);
			Long m=Long.parseLong(str.split("小时")[1].replaceAll("[^(0-9)]", ""));
			Long stayTimes=0l;
			stayTimes=h*60+m;
			return stayTimes*60*1000;//毫秒
		}		
		return null;
	}
	
	/**
	 * 排序税费
	 * Map<String,String>
	*/
	public String[] priceS(Map<String,String>pricStr){
		//最高，最低两个价格
		String[] priceStr=new String[2];
		double h=0.0;
		double d=99999999.0;
		for(Map.Entry<String, String> str:pricStr.entrySet()){
			if(Double.parseDouble(str.getKey())>h){
				h=Double.parseDouble(str.getKey());
			}
			if(Double.parseDouble(str.getKey())<d){
				d=Double.parseDouble(str.getKey());
			}
		}
		priceStr[0]=h+"";
		priceStr[1]=d+"";
		return priceStr;
	}
	
	/**
	 * 国际往返_日期处理
	 */	
	private Date getDates(String dateStr) throws Exception{
		dateStr=dateStr.replaceAll("T", " ");
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		Date queryDates=sdf.parse(dateStr);
		return queryDates;
	}
	
	@Override
	public Object fetch(String url) throws Exception {
		switch (super.getRouteType()) {
		case INTERNATIONAL_ROUND:
			return fetchDoubleI();//国际往返
		case INTERNATIONAL_ONEWAY:
			return fetchInternationalSI();//国际单程
		case DOMESTIC_ONEWAYTRIP:
			return fetchSI();//国内单程（老适配器，不太确定是不是国内单程？？？）
		case DOMESTIC_ROUNDTRIP:
			return null;
		}
		return null;
	}
	/**
	 * 	国内单程（老适配器，不太确定是不是国内单程？？？）
	*/
	public Object fetchSI() throws Exception {
		HttpClient httpClient=null ;
		
		HttpPost httpPost = null;
		HttpResponse httpResponse = null;
		HttpEntity entity = null;
		InputStream gis = null;
		ByteArrayOutputStream os = null;
		InputStream is = null;
		DocumentBuilderFactory factory = null;
		DocumentBuilder parser = null;
		Document d = null;
		net.htmlparser.jericho.Source source = null;
		
		try{
			httpClient = this.getHttpClient();
			 httpPost = new HttpPost(getUrl());
			
			httpPost.setHeader("x-requested-with", "XMLHttpRequest");
			httpPost.setHeader("Accept-Language", "zh-cn");
			httpPost.setHeader("Referer","http://b2c.csair.com/B2C40/modules/booking/basic/flightSelectDirect.jsp");
			httpPost.setHeader("Accept", "application/xml, text/xml, */*; q=0.01");
			httpPost.setHeader("Accept-Encoding", "gzip, deflate");
			httpPost.setHeader("Host", "b2c.csair.com");
			httpResponse = httpClient.execute(httpPost);
			entity = httpResponse.getEntity();
			 
			
			if(entity != null){
				factory = DocumentBuilderFactory.newInstance();
				parser = factory.newDocumentBuilder();
				d = parser.parse(new ByteArrayInputStream(EntityUtils.toByteArray(entity)));
//				source=new Source(entity.getContent());
				TransformerFactory   tf   =   TransformerFactory.newInstance();
				javax.xml.transform.Transformer t = tf.newTransformer();
				ByteArrayOutputStream   bos   =   new   ByteArrayOutputStream();
				t.transform(new DOMSource(d), new StreamResult(bos));
//				super.setSourceWebPageContents(source.getParseText().toString());//存入网页原数据
//				int lenght = EntityUtils.toByteArray(entity).length;//设置流量统计
				super.appendPageContents(bos.toString());//存入网页原数据
				int lenght=countLength(d);//bos.toString().getBytes().length;//设置流量统计
				setLenghtCount( lenght);
				if(bos.toString().contains("<MESSAGE>{routeQueryError}</MESSAGE>")){
					IS_FLIGHTS=false;
				}
			}
			if(TStr(d).length()<2000) rollbackProxyIp(false);
			return d;
		}finally{
			 httpPost = null;
			 httpResponse = null;
			 entity = null;
			 if(os != null) 
				 try{os.close();}catch(Exception e){}
			 if(gis != null) 
				 try{gis.close();}catch(Exception e){}
			  gis = null;
			  os = null;
				 factory = null;
				 parser = null;
		}
		
	}
	
	/**
	 * 国际单程
	*/
	public Object fetchInternationalSI() throws Exception {
		HttpClient httpClient = null;
		
		HttpPost httpPost = null;
		HttpResponse httpResponse = null;
		HttpEntity entity = null;
		 InputStream gis = null;
		 ByteArrayOutputStream os = null;
		InputStream is = null;
		DocumentBuilderFactory factory = null;
		DocumentBuilder parser = null;
		Document d = null;
		net.htmlparser.jericho.Source source = null;
		try{
			 httpClient = this.getHttpClient();
			 httpPost = new HttpPost(getUrlInternationalSI());
			httpPost.setHeader("x-requested-with", "XMLHttpRequest");
			httpPost.setHeader("Accept-Language", "	zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
			httpPost.setHeader("Referer","http://b2c.csair.com/B2C40/modules/booking/international/flightSelectDirect_inter.jsp");
			httpPost.setHeader("Accept", "application/xml, text/xml, */*; q=0.01");
			httpPost.setHeader("Accept-Encoding", "gzip, deflate");
			httpPost.setHeader("Host", "b2c.csair.com");
			 httpResponse = httpClient.execute(httpPost);
			 entity = httpResponse.getEntity();
			 
			 
			 if(entity != null){
				factory = DocumentBuilderFactory.newInstance();
				parser = factory.newDocumentBuilder();
				d = parser.parse(new ByteArrayInputStream(EntityUtils.toByteArray(entity)));
//				source=new Source(entity.getContent());
//				super.appendPageContents(source.getParseText().toString());//存入网页原数据
//				int lenght = EntityUtils.toByteArray(entity).length;//设置流量统计
				
				TransformerFactory   tf   =   TransformerFactory.newInstance();
				javax.xml.transform.Transformer t = tf.newTransformer();
				ByteArrayOutputStream   bos   =   new   ByteArrayOutputStream();
				t.transform(new DOMSource(d), new StreamResult(bos));
				super.appendPageContents(bos.toString());//存入网页原数据
				int lenght=bos.toString().getBytes().length;//设置流量统计
				super.setLenghtCount( lenght);
			}
			 
			 if(TStr(d).length()<2000) rollbackProxyIp(false);
			return d;
		}finally{
			 httpPost = null;
			 httpResponse = null;
			 entity = null;
			 if(os != null) 
				 try{os.close();}catch(Exception e){}
			 if(gis != null) 
				 try{gis.close();}catch(Exception e){}
			  gis = null;
			  os = null;
				 factory = null;
				 parser = null;
		}
		
	}
	
	/**
	 * 国际——往返
	*/
	public Object fetchDoubleI() throws Exception {
		HttpClient httpClient = null;
		
		HttpPost httpPost = null;
		HttpResponse httpResponse = null;
		HttpEntity entity = null;
		InputStream gis = null;
		ByteArrayOutputStream os = null;
		DocumentBuilderFactory factory = null;
		DocumentBuilder parser = null;
		Document d = null;
		net.htmlparser.jericho.Source source = null;
		
		try{
			if(httpClient ==null){
				//重新拿一个对象（相当拿 了一个新IP）
				httpClient = this.getHttpClient();
			}
		
		httpPost = new HttpPost(getUrlDouble());
		
		httpPost.setHeader("x-requested-with", "XMLHttpRequest");
		httpPost.setHeader("Accept-Language", "	zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
//		httpPost.setHeader("Referer","http://b2c.csair.com/B2C40/modules/booking/basic/flightSelect.jsp");
		httpPost.setHeader("Referer","http://b2c.csair.com/B2C40/modules/booking/international/flightSelectReturn_inter.jsp");
		httpPost.setHeader("Accept", "application/xml, text/xml, */*; q=0.01");
//		httpPost.setHeader("Accept-Encoding", "gzip, deflate");
		httpPost.setHeader("Host", "b2c.csair.com");
		httpResponse = httpClient.execute(httpPost);
		entity = httpResponse.getEntity();
		 
		 if(entity != null){
			
			factory = DocumentBuilderFactory.newInstance();
			parser = factory.newDocumentBuilder();
			d = parser.parse(new ByteArrayInputStream(EntityUtils.toByteArray(entity)));
//			source=new Source(entity.getContent());
//			super.setSourceWebPageContents(source.getParseText().toString());//存入网页原数据
//			int lenght =EntityUtils.toByteArray(entity).length;//设置流量统计
			
			TransformerFactory   tf   =   TransformerFactory.newInstance();
			javax.xml.transform.Transformer t = tf.newTransformer();
			ByteArrayOutputStream   bos   =   new   ByteArrayOutputStream();
			t.transform(new DOMSource(d), new StreamResult(bos));
			int lenght=bos.toString().getBytes().length;
			
			//int lenght=super.getSourceWebPageContents().toString().getBytes().length;//流量统计
			
			if(lenght<1000){//说明在南航官网没有找到数据，跳转到另一网站
				Header[] cookiesVa=httpResponse.getHeaders("Set-Cookie");
				for(int i=0;i<cookiesVa.length;i++){
					if(cookiesVa[i].toString().contains("http://")){
						//获取对应CNT
						CNT=RegHtmlUtil.regStr(cookiesVa[i].toString(),"(\"([^\"]*)\")").replaceAll("\"", "").split("ENCT=1")[1];
						break;
					}
				}
				String sources=null;
				String sessionInfo=null;
				if(CNT !=null && !CNT.equals("")){
					httpPost = new HttpPost("http://wftc3.e-travel.com/plnext/CAZG/Override.action?LANGUAGE=CN&EMBEDDED_TRANSACTION=AirAvailability&SITE=CAZGCAZG&ENCT=1&ENC="+CNT);
					httpPost.setHeader("x-requested-with", "XMLHttpRequest");
					httpPost.setHeader("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
					httpPost.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
					//httpPost.setHeader("Accept-Encoding", "gzip, deflate");
					httpPost.setHeader("Host", "wftc3.e-travel.com");
					httpPost.setHeader("Referer","http://b2c.csair.com/B2C40/modules/booking/international/flightSelectReturn_inter.jsp");
					httpResponse = httpClient.execute(httpPost);
					entity = httpResponse.getEntity();
					if(entity != null){
						source=new Source(entity.getContent());
						//单独处理此HTML，获取对应的session信息str
						sessionInfo=getSessionInfo(source);
						if(sessionInfo !=null && !sessionInfo.equals("")){
							String Aurl="http://wftc3.e-travel.com/plnext/CAZG/Fare.action;"+sessionInfo+"?SITE=CAZGCAZG&LANGUAGE=CN&CABIN=E&PAGE_TICKET=0&PLTG_SEARCH_RECAP_UPDATED=true&RESTRICTION=true&ROW_1=0&ROW_2=0&TRIP_TYPE=R";
							logger.info("进入Amadues网站....");
							sources="";
							httpPost = new HttpPost(Aurl);
							httpResponse = httpClient.execute(httpPost);
							entity = httpResponse.getEntity();
							if(entity !=null){
								source=new Source(entity.getContent());
								sources=source.getParseText().toString();
								logger.info("成功获取Amadues网站数据！");
							}
						}
						
						lenght =sources.length();//设置流量统计
					}
				}
				
				d=null;
				while(backCount-->0){
					//递归执行
					logger.info("从Amadues网站回滚回南航官网...");
					super.appendPageContents(bos.toString());//存入网页原数据
					try{
						logger.info(String.format("【%s】毫秒后回滚！", sleepTime));
						Thread.sleep(sleepTime);
						d=(Document) fetchDoubleI();
					}catch (Exception e) {
						logger.error("回滚失败，返回Amadues数据！");
						super.appendPageContents(sources);//存入网页原数据
						selectMethod=false;
						return sources;
					}
				}
				if(countLength(d)<5000){//执行完递归，还是取不回数据就返回之前的数据
					selectMethod=false;
					super.appendPageContents(sources);//存入网页原数据
					return sources;//html
				}
			}
			super.setLenghtCount( lenght);
		}
		 selectMethod=true;
		 super.appendPageContents(TStr(d));//存入网页原数据
		 if(TStr(d).length()<3000) rollbackProxyIp(false);
		 return d;
		 
		}finally{
			httpPost = null;
			 httpResponse = null;
			 entity = null;
			 if(os != null) 
				 try{os.close();}catch(Exception e){}
			 if(gis != null) 
				 try{gis.close();}catch(Exception e){}
			  gis = null;
			  os = null;
				 factory = null;
				 parser = null;
		}
	}
	
	@Override
	public boolean validateFetch(Object fetchObject) throws Exception {
		if(fetchObject == null){
			return false;
		}else if(fetchObject instanceof String){
			//验证字符串里是否包含抓取的错误信息
			String result = RegHtmlUtil.regStr((String)fetchObject, this.getErrors());
			if(result != null){
				throw new PageErrorResultException(result);
			}
		}else if(StringUtils.isNotBlank(getSourceWebPageContents()) && taskQueue.getIsInternational()>0){
			if(countLength((Document) fetchObject) < 2000){
				throw new PageErrorResultException("抓取的数据不正确(长度少于2000)");
			}
			//验证字符串里是否包含抓取的错误信息
			String result = RegHtmlUtil.regStr(getSourceWebPageContents(), this.getErrors());
			if(result != null){
				throw new PageErrorResultException(result);
			}
		}
		return true;
	}	
	
	/**
	 * Beijing, 中国 - Capital International, 候机楼 2
	 * 解释出airportName
	*/
	public String TairportName(String str){
		String airportName=null;
		if(str !=null && !str.equals("")){
			String allStr[]=str.split(",");
//			RegHtmlUtil.regStr(allStr[1].split("\\-")[1],"(^[a-zA-Z])");
			airportName=allStr[1].split("-")[1];
		}
		return airportName;
	}
	
	/**
	 * 日期加减
	*/
	public String addDate(String date,int intDate){
		String dateStr="";
		if(date !=null && !date.equals("") && intDate !=0){
			dateStr=DateUtil.formatDay(DateUtils.addDays(DateUtil.StringToDate("yyyy-MM-dd",date), intDate),"yyyy-MM-dd");
		}else{
			dateStr=date;
		}
		
		return dateStr;
	}
	
	/**
	 * 计算Entity长度legth
	*/
	public int countLength(Document d){
		int length=0;
		try{
			TransformerFactory   tf   =   TransformerFactory.newInstance();
			javax.xml.transform.Transformer t = tf.newTransformer();
			ByteArrayOutputStream   bos   =   new   ByteArrayOutputStream();
			t.transform(new DOMSource(d), new StreamResult(bos));
			length=bos.toString().getBytes().length;
		}catch (Exception e) {
			logger.error("计算长度有误!");
			e.printStackTrace();
		}
		return length;
	}
	/**
	 * Document 转成String
	*/
	public String TStr(Document d){
		String str=null;
		try{
			TransformerFactory   tf   =   TransformerFactory.newInstance();
			javax.xml.transform.Transformer t = tf.newTransformer();
			ByteArrayOutputStream   bos   =   new   ByteArrayOutputStream();
			t.transform(new DOMSource(d), new StreamResult(bos));
			str=bos.toString();
		}catch (Exception e) {
			logger.error("转String失败!");
			e.printStackTrace();
		}
		return str;
	}
	
	
	/**
	 * 中转时间计算
	*/
	public Long Ttime(String str){
		long Ttimes=0l;
		String timeStr=null;
		timeStr=RegHtmlUtil.regStr(str,"(\\d{1,2}+小时\\d{1,2}+分|\\d{1,2}+分)");
		Long hourts=0l,min=0l;
		if(timeStr !=null && !timeStr.equals("")){
			if(timeStr.contains("小时")){
				hourts=Long.parseLong(timeStr.split("小时")[0]);
				min=Long.parseLong(RegHtmlUtil.regStr(timeStr.split("小时")[1],"(\\d{1,2})"));
			}else{
				min=Long.parseLong(RegHtmlUtil.regStr(timeStr,"(\\d{1,2})"));
			}
		}
		Ttimes=(hourts*60+min)*60*1000;
		return Ttimes;
	}
			
	
	//06:10 +1 天  
	public String TflightTime(String str,String flgithDateStr){
		String flightStr=null;
		if(str !=null){
			String timeS=str.split(" ")[0];
			int addI=Integer.parseInt(str.split(" ").length >2?str.split(" ")[1]:"0");
			flightStr=DateUtil.formatDay((DateUtils.addDays(DateUtil.StringToDate("yyyy-MM-dd HH:mm", flgithDateStr+" "+timeS), addI)),"yyyy-MM-dd HH:mm");
		}
		
		return flightStr;
	}
	
	private List<String> getErrors(){
		List<String> airChinaErrors = new ArrayList<String>();
		airChinaErrors.add("404 Not Found");
		airChinaErrors.add("<MESSAGE>NoRoutingException:");
		return airChinaErrors;
	}

}
